home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / NR4SUBR.C < prev    next >
C/C++ Source or Header  |  1996-12-23  |  5KB  |  240 lines

  1. /*
  2.  * nr4subr.c:  subroutines for net/rom transport layer.
  3.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  4.  * non-commercial distribution only.
  5.  */
  6.  
  7. #include "global.h"
  8. #ifdef NETROM
  9. #include "mbuf.h"
  10. #include "timer.h"
  11. #include "ax25.h"
  12. #include "netrom.h"
  13.  
  14. #if !defined(_lint)
  15. static char rcsid[] OPTIONAL = "$Id: nr4subr.c,v 1.12 1996/12/23 20:37:36 root Exp root $";
  16. #endif
  17.  
  18.  
  19.  
  20. /* Get a free circuit table entry, and allocate a circuit descriptor.
  21.  * Initialize control block circuit number and ID fields.
  22.  * Return a pointer to the circuit control block if successful,
  23.  * NULLNR4CB if not.
  24.  */
  25.  
  26. struct nr4cb *
  27. new_n4circ ()
  28. {
  29. int i;
  30. struct nr4cb *cb;
  31.  
  32.     for (i = 0; i < NR4MAXCIRC; i++)    /* find a free circuit */
  33.         if (Nr4circuits[i].ccb == NULLNR4CB)
  34.             break;
  35.  
  36.     if (i == NR4MAXCIRC)    /* no more circuits */
  37.         return NULLNR4CB;
  38.  
  39.     cb = Nr4circuits[i].ccb =
  40.         (struct nr4cb *) callocw (1, sizeof (struct nr4cb));
  41.  
  42.     cb->mynum = (int16) i;
  43.     cb->myid = Nr4circuits[i].cid;
  44.     return cb;
  45. }
  46.  
  47.  
  48. /* Set the window size for a circuit and allocate the buffers for
  49.  * the transmit and receive windows.  Set the control block window
  50.  * parameter.  Return 0 if successful, -1 if not.
  51.  */
  52.  
  53. int
  54. init_nr4window (struct nr4cb *cb, unsigned window)
  55. {
  56.     if (window == 0 || window > NR4MAXWIN)    /* reject silly window sizes */
  57.         return -1;
  58.  
  59.     cb->txbufs = (struct nr4txbuf *) callocw (window, sizeof (struct nr4txbuf));
  60.     cb->rxbufs = (struct nr4rxbuf *) callocw (window, sizeof (struct nr4rxbuf));
  61.     cb->window = window;
  62.     return 0;
  63. }
  64.  
  65.  
  66. /* Free a circuit.  Deallocate the control block and buffers, and
  67.  * increment the circuit ID.  No return value.
  68.  */
  69.  
  70. void
  71. free_n4circ (struct nr4cb *cb)
  72. {
  73. unsigned circ;
  74.  
  75.     if (cb == NULLNR4CB)
  76.         return;
  77.  
  78.     circ = cb->mynum;
  79.  
  80.     if (cb->txbufs != (struct nr4txbuf *) 0)
  81.         free (cb->txbufs);
  82.  
  83.     if (cb->rxbufs != (struct nr4rxbuf *) 0)
  84.         free (cb->rxbufs);
  85.  
  86.     /* Better be safe than sorry: */
  87.  
  88.     free_q (&cb->txq);
  89.     free_q (&cb->rxq);
  90.  
  91.     free (cb);
  92.  
  93.     if (circ > (unsigned) NR4MAXCIRC)    /* Shouldn't happen. */
  94.         return;
  95.  
  96.     Nr4circuits[circ].ccb = NULLNR4CB;
  97.     Nr4circuits[circ].cid++;
  98. }
  99.  
  100.  
  101. /* See if any open circuit matches the given parameters.  This is used
  102.  * to prevent opening multiple circuits on a duplicate connect request.
  103.  * Returns the control block address if a match is found, or NULLNR4CB
  104.  * otherwise.
  105.  */
  106.  
  107. struct nr4cb *
  108. match_n4circ (theindex, id, user, node)
  109. int theindex;            /* index of remote circuit */
  110. int id;                /* id of remote circuit */
  111. char *user;            /* address of remote user */
  112. char *node;            /* address of originating node */
  113. {
  114. int i;
  115. struct nr4cb *cb;
  116.  
  117.     for (i = 0; i < NR4MAXCIRC; i++) {
  118.         if ((cb = Nr4circuits[i].ccb) == NULLNR4CB)
  119.             continue;    /* not an open circuit */
  120.         if (cb->yournum == (unsigned) theindex && cb->yourid == (unsigned) id
  121.             && addreq (cb->remote.user, user)
  122.             && addreq (cb->remote.node, node))
  123.             return cb;
  124.     }
  125.     /* if we get to here, we didn't find a match */
  126.  
  127.     return NULLNR4CB;
  128. }
  129.  
  130.  
  131. /* Validate the index and id of a local circuit, returning the control
  132.  * block if it is valid, or NULLNR4CB if it is not.
  133.  */
  134.  
  135. struct nr4cb *
  136. get_n4circ (theindex, id)
  137. int theindex;            /* local circuit index */
  138. int id;                /* local circuit id */
  139. {
  140. struct nr4cb *cb;
  141.  
  142.     if (theindex >= NR4MAXCIRC)
  143.         return NULLNR4CB;
  144.  
  145.     if ((cb = Nr4circuits[theindex].ccb) == NULLNR4CB)
  146.         return NULLNR4CB;
  147.  
  148.     if (cb->myid == (unsigned) id)
  149.         return cb;
  150.     else
  151.         return NULLNR4CB;
  152. }
  153.  
  154.  
  155. /* Return 1 if b is "between" (modulo the size of an unsigned char)
  156.  * a and c, 0 otherwise.
  157.  */
  158.  
  159. int
  160. nr4between (a, b, c)
  161. unsigned a, b, c;
  162. {
  163.     if ((a <= b && b < c) || (c < a && a <= b) || (b < c && c < a))
  164.         return 1;
  165.     else
  166.         return 0;
  167. }
  168.  
  169.  
  170. /* Set up default timer values, etc., in newly connected control block.
  171.  */
  172.  
  173. void
  174. nr4defaults (struct nr4cb *cb)
  175. {
  176. int i;
  177. struct timer *t;
  178.  
  179.     if (cb == NULLNR4CB)
  180.         return;
  181.  
  182.     /* Set up the ACK and CHOKE timers */
  183.  
  184.     set_timer (&cb->tack, Nr4acktime);
  185.     cb->tack.func = nr4ackit;
  186.     cb->tack.arg = cb;
  187.  
  188.     set_timer (&cb->tchoke, Nr4choketime);
  189.     cb->tchoke.func = nr4unchoke;
  190.     cb->tchoke.arg = cb;
  191.  
  192.     cb->rxpastwin = uchar (cb->window);
  193.  
  194.     /* Don't actually set the timers, since this is done */
  195.     /* in nr4sbuf */
  196.  
  197.     for (i = 0; (unsigned) i < cb->window; i++) {
  198.         t = &cb->txbufs[i].tretry;
  199.         t->func = nr4txtimeout;
  200.         t->arg = cb;
  201.     }
  202. }
  203.  
  204.  
  205. /* See if this control block address is valid */
  206.  
  207. int
  208. nr4valcb (struct nr4cb *cb)
  209. {
  210. int i;
  211.  
  212.     if (cb == NULLNR4CB)
  213.         return 0;
  214.  
  215.     for (i = 0; i < NR4MAXCIRC; i++)
  216.         if (Nr4circuits[i].ccb == cb)
  217.             return 1;
  218.  
  219.     return 0;
  220. }
  221.  
  222.  
  223. #ifdef MSDOS
  224.  
  225. void
  226. nr_garbage (int red)
  227. {
  228. int i;
  229. struct nr4cb *ncp;
  230.  
  231.     for (i = 0; i < NR4MAXCIRC; i++) {
  232.         ncp = Nr4circuits[i].ccb;
  233.         if (ncp != NULLNR4CB)
  234.             mbuf_crunch (&ncp->rxq);
  235.     }
  236. }
  237.  
  238. #endif
  239. #endif /* NETROM */
  240.